<?php

/** Dataxi menu bar
 *  This code is licensed under GPL2.
 *  See LICENSE or www.gnu.org for more details.
 *  @author Henri Ranki
 *
 *  $Id: dzmenu.php 595 2006-04-03 16:00:47Z jyry $
 */

include_once("sodebug.php");
include_once("sogeneric.php");
include_once("soinifiles.php");
include_once("sostreams.php");

include_once("dzconst.php");
include_once("dzgeneric.php");

/** Menu related constants */
define(DZMP_SOURCE, "source");      /* Source file menu property key */
define(DZMP_ULEVEL, "user_level");  /* User level */
define(DZMP_UGROUPS, "groups");     /* User groups */


/** A class that contains the structure of the Dataxi application menu
 *  a menu.ini (default) is read in and the menu is constructed acording
 *  to that. ini-file could be overidden in constructor
 *  @param array/soSet $MenuStruct An array of main menu (dropdown boxes).
 *      Each item  contains a set of sub items.
 */
class dzMenu {
    var $MenuStruct;
    var $__Widths;      /** soSet/int Widths of the menus in characters. */


    /** Gets menu ini as a string.
     *  Reads in menu, modifies form paths and returns it as a string.
     *  @param string $MenuName Menu name ro read in.
     *  @return string Menu ini string
     */
    function __readMenu($MenuName, $FormsPath) {
        /* Read the menu definition from the ini file */
        $ini = new soIniData($MenuName);
        if ($ini->Error) {
            dzSysError("Could Not find menu definition from $MenuName");
        } // if

        $sect_count= $ini->getSectionCount();
        for ($s = 0; $s < $sect_count; $s++) {
            $item_no = 0;
            $value = $ini->getSetValue($s, $item_no, DZMP_SOURCE);
            while (!$ini->Error) {
                $action = dzParseMenuTarget($value);
                switch ($action->Target) {
                    case DZMT_NALLE:
                        $split = soSplitStr($value, "://", 1, 1);
                        $value = $split[0].$FormsPath.$split[1];
                        $value = str_replace("~", dzGetMainScriptPath(), $value);
                        break;

                    case DZMT_EXT_WINDOW:
                        $value = $action->Stream;
                        break;
                } // switch

                $ini->setSetValue($ini->CurrentSectionName,
                                  $ini->getCurrentKeyName(),
                                  DZMP_SOURCE, $value);
                $value = $ini->getSetValue($s, ++$item_no, DZMP_SOURCE);
            }; // while
        }; // for

        return $ini->getIniString();
    } // __readMenu


    /** Sets up menu
     *  Reads in the ini-files and initializes __MenuStruct property. You
     *  can give a parameter that specifies where to read menu information.
     *  Default is menu.ini.
     *  @param array/string $UserGroups Groups the users belongs to
     *  @param int $UserLevel The user level
     *  @param string $MenuName The stream where the menu definition is read
     *  @param string Language Language code
     */
    function __setupMenu($UserGroups, $UserLevel, $MenuName,
                         $Language = "default") {
        $Language = strtolower($Language);
        if (!$Language) $Language = "default";

        /* Get the user level where starts admin users */
        $admin_level = dzGetIniItem(DZIS_SYS,
                                    DZID_ADMIN_USER_LEVEL,
                                    "dataxi");

        $MenuName = "file://".$MenuName.".";
        $this->MenuStruct = array();
        $this->__Widths = new soSet();

        /* Read the menu definition from the ini file */
        $forms_path = dzGetIniPath(DZID_FORM_SOURCE_FOLDER)."/";
        $ini_str = $this->__readMenu($MenuName."ini", $forms_path);

        /* Read the translations from the file */
        $transl_ini_stream = new soInputStream($MenuName."txt");
        $transl_ini_str = $transl_ini_stream->Data;

        /* Add system menu, if user is admin */
        if ($UserLevel >= $admin_level) {
            $sys_folder = dzGetDataxiPath();
            $sys_menu_file = "file://$sys_folder/".
                             dzGetIniItem(DZIS_SYS,
                             DZID_ADMIN_MENU_FILE,
                             "dataxi");
            $forms_path = "$sys_folder/".DZIS_DIALOGS;
            $ini_str .= "\n".$this->__readMenu($sys_menu_file,
                                               $forms_path."/");

            /* Read the translations from the file */
            $dot_pos = soLocateStr($sys_menu_file, ".", -1);
            $sys_transl_ini = substr($sys_menu_file, 0, $dot_pos +1)."txt";
            $transl_ini_stream = new soInputStream($sys_transl_ini);
            if ($transl_ini_stream->Error) {
                dzSysError("Could not find system menu translations in: ".
                           "$sys_transl_ini");
            } // if
            $transl_ini_str .= "\n".$transl_ini_stream->Data;
        }; // if ($UserLevel > $admin_level)

        /* Read the Ini stream */
        $iniFile = new soIniData($ini_str);
        $translations = new soIniData($transl_ini_str);

        /* Strict menu access? Check it from app ini */
        $strict_access = dzGetIniItem(DZIS_GENERAL,
                                      "strict_menu_access", "app", "bool");

        $menugroup = "";
        $sectionCount = $iniFile->getSectionCount();
        for ($c = 0; $c < $sectionCount; $c++) {

            /* Check group rights of a menu */
            $groups = soExplode($iniFile->getValue($c, "groups"), ",");
            if (!count($groups)) {
                $group_ok = (!$strict_access);
                $key_no = 0;
            } else {
                $group_ok = soInArray($limit_groups, $UserGroups);
                $key_no = 1;
            }; // if

            /* Check user level rights for a menu */
            $level = $iniFile->getValue($c, DZMP_ULEVEL);
            if (!$level) {
                $level_ok = (!$strict_access);
            } else {
                $level_ok = ($UserLevel >= $level);
            }; // if

            /* Admin has access to everything */
            if ($UserLevel >= $admin_level) {
                $group_ok = 1;
                $level_ok = 1;
            }; // if

            /* Only add an menu enty if group & level are accepted */
            if ($group_ok && $level_ok) {
                $menu_no = 1;
                $max_width = -1;
                $itemSet = new soSet();
                $iniFile->findSection($c);
                $section = $iniFile->CurrentSectionName;
                do {
                    $prop_set = $iniFile->getValueSet($c, $key_no);
                    $prop_name = $iniFile->getCurrentKeyName();
                    $out_name = $translations->getSetValue($section,
                                                           $prop_name,
                                                           $Language);
                    if (!$out_name) {
                        $out_name = $translations->getSetValue($section,
                                                               $prop_name,
                                                               "default");
                    }; // if
                    if (!$out_name) $out_name = $prop_name;

                    $source = $prop_set->getItem(DZMP_SOURCE);
                    $max_width = max($max_width, strlen($out_name));
                    if ((!$iniFile->getError()) && $source) {
                        /* Check group rights of a menu entry */
                        $groups = soExplode($prop_set->getItem(DZMP_UGROUPS), ",");
                        if (!count($groups)) {
                            $group_ok = (!$strict_access);
                        } else {
                            $group_ok = soInArray($limit_groups, $UserGroups);
                        }; // if

                        /* Check user level rights for a menu entry */
                        $level = $prop_set->getItem(DZMP_ULEVEL);
                        if (!$level) {
                            $level_ok = (!$strict_access);
                        } else {
                            $level_ok = ($UserLevel >= $level);
                        }; // if

                        /* Admin has access to everything */
                        if ($UserLevel >= $admin_level) {
                            $group_ok = 1;
                            $level_ok = 1;
                        }; // if

                        if ($group_ok && $level_ok) {
                            $itemSet->setItem(($menu_no++)." ".$out_name,
                                               $source);
                        }; // if user_level >
                    }; // if
                    $key_no++;
                } while (!$iniFile->getError());
                $out_section = $translations->getSetValue($section, "head",
                                                          $Language);
                if (!$out_section) {
                    $out_section = $translations->getSetValue($section,
                                                              "head",
                                                              "default");
                }; // if
                if (!$out_section) $out_section = $section;
                $this->__Widths->setItem($out_section, $max_width);
                $this->MenuStruct[$out_section] = $itemSet;
            } // if $userlevel

        } // for
    } // __setupMenu


    /** Create menu
     *  Makes the script that is used to construct the Dataz menu bar.
     *  The user level is considered. Menu.ini defines the user level limits
     *  for each drop down box. The users level must be equal or creater than
     *  the limit to have that dorp down box to be shown in the menu.
     *  @param bool true if the session is suspended
     *  @param string $UserName Users name (for displaying only)
     *  @param array/atring $UserGroups An array of user's groups
     *  @param int $UserLevel The users level who will receive the menu.
     *  @param string $MenuName The stream where the menu definition is read
     *  @param string $Language Language code
     *  @return string Script to create menu into menu bar
     */
    function getMenu($Suspend, $UserName, $UserGroups, $UserLevel,
                     $MenuName = "", $Language = "default") {
        include("dzstonga.inc");
        include("sodebug.inc");

        /* no specific ini stream specified? use default then */
        if (!$MenuName) $MenuName = dzGetIniPath(DZID_INI_FOLDER)."/menu";

        if (isset($DZ_STONGA_BUTTONS[$Language])) {
            $buttons = &$DZ_STONGA_BUTTONS[$Language];
        } else {
            $buttons = &$DZ_STONGA_BUTTONS["default"];
        };
        if (isset($DZ_CAPTIONS[$Language])) {
            $captions = &$DZ_CAPTIONS[$Language];
        } else {
            $captions = &$DZ_CAPTIONS["default"];
        };

        /* Read in the menu definition from a menu.ini file */
        $this->__setupMenu($UserGroups, $UserLevel, $MenuName, $Language);
        $html = "<HTML><HEAD>\n".
                dzGetStyleBlock(DZCSS_BAR).
                "</HEAD><BODY><FORM>\n".
                "<TABLE WIDTH=100% BORDER=0 CELLSPACING=0 cellpadding=0>".
                "<TR valign=top>\n";

        if (!$Suspend) {
            $html .= "<td width=*>";
            while (list ($key, $val) = each ($this->MenuStruct)) {
                $itemArr = $val->getAsArray();
                $size = count($itemArr);
                $html .= "<SELECT NAME='".$key."' SIZE=1 ".
                         "OnChange=\\\"top.nalle.".
                         "selectWrapper('menu','ENewView',this);\\\">\n".
                         "<OPTION VALUE=''>".$key."\n".
                         "<OPTION VALUE=''>".$line."\n";
                while (list($title, $file) = each($itemArr)) {
                    /* Replace underscores with spaces */
                    $title = soSwapStr($title, "_", " ");
                    $html .= "<OPTION VALUE='".$file."'>".$title."\n";
                }; // while
                $html .= "</OPTION></SELECT>\n";
            }; // while
            $html .= "</TD>\n";
        } // if

        $caption = $captions[DZSC_LOGINNAME];
        if (!$caption) $caption = DZSC_LOGINNAME;
        $button = $buttons[DZSE_EXIT];
        if (!$button) $button = DZSE_EXIT;
        $html .= "<TD width=1% align=left>".
                 "<B>".$UserName.
                 "</B></td><td width=1%>";

        if (!$Suspend) {
            $html .= "<INPUT TYPE=BUTTON NAME='EExit' VALUE='".
                     $buttons[DZSE_EXIT].
                     "' OnClick=\\\"top.nalle.confirmExit(this);\\\">\n";
        } // if
        $html .= "</TD></TR></TABLE>\n</FORM></BODY></HTML>";

        /* Add JavaScript that writes the html produced above to the
         * menu bar */
        $result = "MenuPtr = parent.menu.document;\n";
        
        /* Put all menu html to one line or many based on debug level */
        if ($SoDebugLevel >= SOD_DET) {
            $scriptLines = soExplode($html, "\n");
        } else {
            $scriptLines = array(str_replace("\n", " ", $html));
        };
        
        $icount = count($scriptLines);
        for ($c = 0; $c < $icount; $c++) {
            $result .= "MenuPtr.writeln(\"".$scriptLines[$c]."\");\n";
        }
        $result .= "MenuPtr.close();\n";

        return $result;
    } // getMenu

}; //dzMenu


/** Generic menu class for both menu and menu items.
 *  @var int $UserLevel User level
 *  @var array/string $Groups Group names
 *  @var string $Caption Text to display instead of menu tag.
 */
class __dzMenu_generic {
    var $UserLevel;
    var $Groups;
    var $Caption;

    /** Constructor
     */
    function __dzMenu_generic() {
        $this->Groups = array();
    } // __dzMenu_generic

}; // __dzMenu_generic


/** Menu item.
 *  @var string $Menu Menu name
 *  @var string $Target Target to call when selected
 */
class __dzMenuItem extends __dzMenu_generic {
    var $Menu;
    var $Target;
}; // __dzMenuItem


/** Menu.
 *  @var array/dzMenu $SubMenus Sub menu objects
 *  @var array/dzMenuItem $Items Menu items
 */
class __dzMenu extends __dzMenu_generic {
    var $SubMenus;
    var $Items;

    /** Constructor
     */
    function __dzMenu() {
        $this->SubMenus = array();
        $this->Items = array();
    } // __dzMenu


}; // __dzMenu


/** Actual menu structure to hold all menu items and sub-menus
 *  @param __dzMenu $__Menu Menu structure.
 *  @param array/array Index for all menus for quick seach. Each primary
 *      array element has unique menu tag name as key and contains an array
 *      that contains the menu chain where to find the menu in the tree.
 */
class __dzMenuStruct {
    var $__Menu;
    var $__Index;

    /** Constructor - initialises the object
     */
    function __dzMenuStruct() {
        $this->__Menu = new __dzMenu();
        $this->__Index = array();
    } // __dzMenuStruct


    /** Adds another menu to the structure.
     *  @var string $Name Name of the menu
     *  @var string $Caption Display name of the menu
     *  @var string $Parent Name of the parent menu. This must be empty/NULL
     *      when refering to the main level menu.
     *  @var int $UserLevel User level to access this menu
     *  @var array/string $Groups Groups names to access this menu
     *  @return True(1) when all fine, false(0) when menu by the same name
     *      already exists in the menu system or parent does not.
     */
    function addMenu($Name, $Caption, $Parent, $UserLevel, $Groups) {
        /* No duplicates *and* parent must exists or be NULL */
        $chain = $this->__Index[$Name];
        if ($chain != NULL) return 0; // <-- EXIT
        $pchain = $this->__Index[$Parent];
        if (($Parent != NULL) && ($pchain == NULL)) return 0; // <-- EXIT

        /* All fine this far. Add the menu. */
        if ($pchain == NULL) $chain = array();
        if ($this->__addMenu_sub($Name, $Caption, $this->__Menu, $chain,
                                 $UserLevel, $Groups)) {
            $this->__Index[$Name] = array_merge($chain, $Name);
        }; // if
        return 1;
    } // addMenu


    /** Used by addMenu to loop through chain and add the menu.
     */
    function __addMenu_sub($Name, $Caption, &$Menu, $Chain,
                           $UserLevel, $Groups) {
        if (count($Chain)) {
            $sub_menu = &$Menu->SubMenus[$Chain[0]];
            soDelElement($Chain, 0);
            $this->__addMenu_sub($Name, $Caption, $sub_menu, $Chain,
                                 $UserLevel, $Groups);
            $result = 0;
        } else {
            $new_menu = new __dzMenu();
            $new_menu->Caption = $Caption;
            $new_menu->Userlevel = $UserLevel;
            $new_menu->Groups = $Groups;
            $Menu->SubMenus[$Name] = $new_menu;
            $result = 1;
        }; // else if
        return $result;
    } // __addMenu_sub


    /** Adds another menu item to the structure.
     *  @var string $Name Name of the menu item
     *  @var string $Caption Display name of the menu item
     *  @var string $Menu Name of the menu this belongs to
     *  @var string $Target Target to call when selected
     *  @var int $UserLevel User level to access this menu
     *  @var array/string $Groups Groups names to access this menu
     *  @return True(1) when all fine, false(0) when menu name is not found
     *      or item name already exists.
     */
    function addMenuItem($Name, $Caption, $Menu, $Target, $UserLevel, $Groups) {
        /* Menu must exists or be NULL */
        $pchain = $this->__Index[$Menu];
        if (($Menu != NULL) && ($pchain == NULL)) return 0; // <-- EXIT

        /* All fine this far. Add the menu. */
        if ($pchain == NULL) $pchain = array();
        if ($this->__addMenuItem_sub($Name, $Caption, $this->__Menu, $pchain,
                                     $UserLevel, $Groups)) {
        }; // if
        return 1;
    } // addMenuItem


    /** Used by addMenuItem to loop through chain and add a menu item.
     */
    function __addMenuItem_sub($Name, $Caption, &$Menu, $Chain,
                               $UserLevel, $Groups) {
        if (count($Chain)) {
            $sub_menu = &$Menu->SubMenus[$Chain[0]];
            soDelElement($Chain, 0);
            $this->__addMenuItem_sub($Name, $Caption, $sub_menu, $Chain,
                                 $UserLevel, $Groups);
        } else {
            $new_item = new __dzMenu();
            $new_item->Caption = $Caption;
            $new_item->Userlevel = $UserLevel;
            $new_item->Groups = $Groups;
            $Menu->Items[$Name] = $new_item;
        }; // else if
    } // __addMenu_sub


    /** Returns the menu object.
     *  @return __dzMenu The menu object.
     */
    function getMenu() {
        return $this->__Menu;
    } // getMenu


}; // __dzMenuStruct


/** Sub-routine for __dzSetupmenu
 *  @param DZMI_* $Section Section to read and setup.
 *  @param dzIni $Ini Ini data to loop
 *  @param dzIni $Txt Ini Translations to loop
 *  @param string $Language Language code
 *  @param __dzMenuStruct $Menus Menu structure
 */
function __dzSetupMenu_sub($Section, &$Ini, &$Txt, $Language, &$Menu) {
    include_once("sodebug.php");
    include("sodebug.inc");
    $soDebugLevel = SOD_DET;
    $soDebugLogFile = "/tmp/menu.log";

    /* Loop all entries in menus section */
    $menucount = $Ini->getValueCount($Section);
    for ($c = 0; $c < $menucount; $c++) {
        $groups = soExplode($Ini->getValue($Section, $c, DZMI_GROUPS), ",");
        $level = $Ini->getValue($Section, $c, DZMI_LEVEL);
        $tag_name = $Ini->getValueName($Section, $c);
        $real_name = $Txt->getValue($Section, $tag_name, $Language);

        if ($Section == DZMI_MENUS) {
            $Menu->addMenu($tag_name, $real_name, $parent, $level, $groups);
        } else {
            $split = soSplitStr($tag_name, ".", 1);
            $menu = $split[0];
            $name = $split[1];
            $Menu->addMenuItem($name, $real_name, $menu,
                               $Ini->getValue($Section, $c, DZMI_LINK),
                               $level, $groups);
        }; // else if

    }; // for

}; // __dzSetupMenu_sub


/** Sets up a menu structure
 *  Reads in the ini-files and initializes __MenuStruct property. You
 *  can give a parameter that specifies where to read menu information.
 *  Default is menu.ini.
 *  @param string $MenuName The stream where the menu definition is read
 *  @param string Language Language code
 */
function __dzSetupMenu($MenuName, $Language) {
    $result = new __dzMenuStruct();

    if (!$Language) $Language = "default";

    /* Get the user level where starts admin users */
    $admin_level = dzGetIniItem(DZIS_SYS,
                                DZID_ADMIN_USER_LEVEL,
                                "dataxi");

    $MenuName = "file://".$MenuName.".";
    $result = new __dzMenuStruct();

    /* Read the menu definition from the ini file */
    $forms_path = dzGetIniPath(DZID_FORM_SOURCE_FOLDER)."/";
    $ini = new soIni($MenuName."ini");
    $txt = new soIni($MenuName."txt");

    $sys_folder = dzGetDataxiPath();
    $sys_menu_file = "file://$sys_folder/".dzGetIniItem(DZIS_SYS,
                     DZID_ADMIN_MENU_FILE, "dataxi");
    $forms_path = "$sys_folder/".DZIS_DIALOGS;
    $ini->read($sys_menu_file);

    /* Read the translations from the file */
    $dot_pos = soLocateStr($sys_menu_file, ".", -1);
    $sys_transl_ini = substr($sys_menu_file, 0, $dot_pos +1)."txt";
    $txt->read($sys_trans_ini);

    /* Strict menu access? Check it from app ini */
    $strict_access = dzGetIniItem(DZIS_GENERAL,
                                  "strict_menu_access", "app", "bool");
    __dzSetupMenu_sub(DZMI_MENUS, $ini, $txt, $Language, $result);
    __dzSetupMenu_sub(DZMI_ITEMS, $ini, $txt, $Language, $result);

    return $result;
}; // __dzSetupMenu


/** Print a menu object.
 *  Returns HTML/JavaScript code to be sent to the browser.
 *  @var dzMenuStruct $Menu Menu object to print.
 *  @var DZMS_* $Style Menu style (see constants at the top of the file)
 *  @var array $Groups User's groups he is memer of
 *  @var int $UserLevel User's level
 *  @return string HTML/JavaScript that prints menu in the browser
 */
function dzPrintMenu(&$Menu, $Style, $Groups, $UserLevel) {

    dzPrintMenu_sub();
    /* Check group rights of a menu */
    $groups = soExplode($Ini->getValue($Section, $c, DZMI_GROUPS), ",");
    if (!count($groups)) {
        $group_ok = (!$strict_access);
        $key_no = 0;
    } else {
        $group_ok = soInArray($limit_groups, $UserGroups);
        $key_no = 1;
    }; // if

    /* Check user level rights for a menu */
    $level = $Ini->getValue($Section, $c, DZMI_LEVEL);
    if (!$level) {
        $level_ok = (!$strict_access);
    } else {
        $level_ok = ($UserLevel >= $level);
    }; // if

    /* Admin has access to everything */
    if ($UserLevel >= $admin_level) {
        $group_ok = 1;
        $level_ok = 1;
    }; // if

    /* Only add an menu entry if group & level are ok */
    if ($group_ok && $level_ok) {
        $parent = $Ini->getValue($Section, $c, DZMI_PARENT);
    } // if
}; // dzPrintMenu


/** Returns JavaScript required to build the menu bar.
 *  Produces the script that is used to construct the Dataz menu bar.
 *  The user level is considered. Menu.ini defines the user level limits
 *  for each drop down box. The users level must be equal or creater than
 *  the limit to have that dorp down box to be shown in the menu.
 *  @param bool true if the session is suspended
 *  @param string $UserName Users name (for displaying only)
 *  @param array/atring $UserGroups An array of user's groups
 *  @param int $UserLevel The users level who will receive the menu.
 *  @param string $MenuName The stream where the menu definition is read
 *  @param string $Language Language code
 *  @return string Script to create menu into menu bar
 */
function dzGetMenu($Suspend, $UserName, $UserGroups, $UserLevel,
                   $MenuName = "", $Language = "default") {

    include("dzstonga.inc");
    include("sodebug.inc");

    /* no specific ini stream specified? use default then */
    if (!$MenuName) $MenuName = dzGetIniPath(DZID_INI_FOLDER)."/menu";

    if (isset($DZ_STONGA_BUTTONS[$Language])) {
        $buttons = &$DZ_STONGA_BUTTONS[$Language];
    } else {
        $buttons = &$DZ_STONGA_BUTTONS["default"];
    }; // else if
    if (isset($DZ_CAPTIONS[$Language])) {
        $captions = &$DZ_CAPTIONS[$Language];
    } else {
        $captions = &$DZ_CAPTIONS["default"];
    }; // else if
    $bg_color = dzGetIniItem(DZCL_SECTION, DZCL_MENU, "app");

    /* Read in the menu definition from a menu.ini file */
    $menu = __dzSetupMenu($MenuName, $Language);
    $result = dzPrintMenu($menu, $UserGroups, $UserLevel);
### Done this far

        $html = "<HTML><HEAD>\n";
        $html .= "</HEAD><BODY bgcolor=$bg_color><FORM>\n";
        $html .= "<TABLE WIDTH=100% BORDER=0 CELLSPACING=4><TR>\n";
        if (!$Suspend) {
            while (list ($key, $val) = each ($this->MenuStruct)) {
                $html .= "<TD>";
                $itemArr = $val->getAsArray();
                $size = count($itemArr);
                $html .= "<SELECT NAME='$key' SIZE=1 ".
                    "OnChange=\\\"top.nalle.selectWrapper('menu','ENewView',this);\\\">\n";
                $html .= "<OPTION VALUE=''>$key\n";
                $width = $this->__Widths->getItem($key);
                $line = soPadStr("", "-", $width);
                $html .= "<OPTION VALUE=''>$line\n";
                while (list ($title, $file) = each ($itemArr)) {
                    /* Replace underscores with spaces */
                    $title = soSwapStr($title, "_", " ");
                    $html .= "<OPTION VALUE='$file'>$title\n";
                }; // while
                $html .= "</OPTION></SELECT>\n";
                $html .= "</TD>\n";
            }; // while
        } // if

        $caption = $captions[DZSC_LOGINNAME];
        if (!$caption) $caption = DZSC_LOGINNAME;
        $button = $buttons[DZSE_EXIT];
        if (!$button) $button = DZSE_EXIT;
        $html .= "<TD>".
                 $captions[DZSC_LOGINNAME].": <B>".$UserName."</B><BR>";

        if (!$Suspend) {
            $html .= "<INPUT TYPE=BUTTON NAME='EExit' VALUE='".
                     $buttons[DZSE_EXIT].
                     "' OnClick=\\\"top.nalle.confirmExit(this);\\\">\n";
        } // if
        $html .="</TD></TR></TABLE>\n";
        $html .= "</FORM></BODY></HTML>";

        /* Add JavaScript that writes the html produced above to the
         * menu bar */
        $result = "MenuPtr = parent.menu.document;\n";
        $scriptLines = soExplode($html, "\n");
        $icount = count($scriptLines);
        for ($c = 0; $c < $icount; $c++) {
            $result .= "MenuPtr.writeln(\"".$scriptLines[$c]."\");\n";
        }
        $result .= "MenuPtr.close();\n";

}; // dzGetMenu


/** Data structure that defines the target of the menu action.
 *  There are two posibilies wheter a new browser window is opened
 *  or a new form is opened into Nalle.
 *  Defines also the source for the form or browser window.
 *  Use dzParseMenuTarget()-function to create class of this type
 *  accerding to the menu item definition.
 *  @var string $Stream The source stream
 *  @var string $Target The target where the source is opened
 *  @var string $Params Optional parameters that should be passed to the
 *  exernal window opening JavaScript call (window.open) as is. This if
 *  filled in by handleSubariEventItem in dzEvent.
 */
class dzMenuTarget {
    var $Stream;
    var $Target;
    var $Params;
}; // dzMenuTarget


/** Parse menu/subari action target and source stream
 *  @param string $Defintion  Menu item definition
 */
function dzParseMenuTarget($Definition) {
    $result = new dzMenuTarget();

    /* Target is the actual target string, but target_type might get tweaked
     * because https and http are considered as just of type http. */
    $target = dzGetValidUrl($Definition);

    /* Sort out the actual target type */
    $target_type = soExtractVal($target, "://", 1);
    $source = soExtractVal($target, "://", 2);
    if (ereg(DZMT_EXT_HTTP_FORM.".*", $target_type)) {
        $target_type = DZMT_EXT_HTTP_FORM;
    };

    /* Act accordingly to the target type */
    switch ($target_type) {
        case DZMT_NALLE_FORM:
            $result->Stream = "file://".$source;
            $result->Target = DZMT_NALLE;
            break;

        case DZMT_NALLE_HTTP_FORM:
            $result->Stream = "http://".$source;
            $result->Target = DZMT_NALLE;
            break;

        case DZMT_EXT_FORM:
            $result->Stream = "file://".$source;
            $result->Target = DZMT_EXT_WINDOW;
            break;

        case DZMT_EXT_HTTP_FORM:
            $result->Stream = $target;
            $result->Target = DZMT_EXT_WINDOW;
            break;

        default:
            $result->Stream = $source;
            $result->Target = $target;
    } // switch

    return $result;
}; // dzParseMenuTarget


/* Test block
$result = new __dzMenuStruct();
$ini = new soIni("file://sysmenu.ini");
$txt = new soIni("file://sysmenu.txt");

__dzSetupMenu_sub(DZMI_MENUS, $ini, $txt, "fi", $result);
__dzSetupMenu_sub(DZMI_ITEMS, $ini, $txt, "fi", $result);
*/

?>
